package v1

import (
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"zimuzu_cvn_web_api/config"
	"zimuzu_cvn_web_api/lib/geetest"
	"zimuzu_cvn_web_api/pkg/errno"
	"zimuzu_cvn_web_api/router/api"
	"zimuzu_cvn_web_api/router/api/app/middleware"
	"zimuzu_cvn_web_api/service"
)

type ValidateAPI struct {
}

func (validate ValidateAPI) Name() string {
	return "validate API"
}

func (validate ValidateAPI) Bind() {
	validateAPI := config.C.Router.Group("/v1/app/validate", middleware.TrackLog())
	{
		validateAPI.POST("getCode", getCode)
		validateAPI.GET("geetestInit", geetestInit)
		validateAPI.POST("verifyCode", verifyCode)
		validateAPI.POST("geetTestValidate", geetTestValidate)
	}

	validateLoginAPI := config.C.Router.Group("/v1/app/validate", middleware.TrackLog(), middleware.AuthMiddleware())
	{
		validateLoginAPI.POST("checkPayPassword", validatePassword)
	}
}

//极验初始化
//Auth: Xu
func geetestInit(c *gin.Context) {
	response := geetest.GeetestInit(c, geetest.ClientTypeAPP)

	errno.OK.Info = "获取成功"
	api.SendResponse(c, errno.OK, response)
	return
}

//极验验证
func geetTestValidate(c *gin.Context) {
	//滑动验证
	_, validateErr := geetest.Validate(c, geetest.ClientTypeAPP)
	if validateErr != nil {
		api.SendResponse(c, validateErr, nil)
		return
	} else {
		errno.OK.Info = "验证成功"
		api.SendResponse(c, errno.OK, nil)
		return
	}
}

type SendCodeParams struct {
	Mobile string `form:"mobile" json:"mobile"`
	Scene  string `form:"scene" json:"scene" binding:"required"`
	Area   int    `form:"area" json:"area"`
}

//发送验证码
//Auth: Xu
func getCode(c *gin.Context) {
	var params SendCodeParams
	err := c.ShouldBindWith(&params, binding.FormPost)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	//滑动验证
	_, validateErr := geetest.Validate(c, geetest.ClientTypeAPP)
	if validateErr != nil {
		api.SendResponse(c, validateErr, nil)
		return
	}
	//已登陆状态下使用已绑定的手机号
	if checkLoginErr := middleware.CheckTokenLogin(c); checkLoginErr == nil {
		uid, _ := service.GetUserIdByRequest(c)
		userInfo, _ := service.GetUserInfo(uid)
		params.Mobile = userInfo.PhoneNumber
		params.Area = userInfo.PhoneArea
	} else if len(params.Mobile) == 0 {
		api.SendResponse(c, errors.New("请填写手机号"), nil)
		return
	}
	//检查账号是否已注册
	res, _ := service.CheckAccountReg(params.Mobile, params.Area)
	if params.Scene == service.SendCodeSceneReg || params.Scene == service.SendCodeSceneInvite {
		if res {
			api.SendResponse(c, errors.New("账号已注册"), nil)
			return
		}
	}
	if params.Scene == service.SendCodeScenePassword {
		if !res {
			api.SendResponse(c, errors.New("账号未注册"), nil)
			return
		}
	}

	//发送短信
	if sendErr := service.SendCode(params.Mobile, params.Scene, params.Area); sendErr != nil {
		api.SendResponse(c, sendErr, nil)
		return
	}

	errno.OK.Info = "发送短信成功"
	api.SendResponse(c, errno.OK, nil)
}

type verifyRegCodeParams struct {
	Mobile string `form:"mobile" json:"mobile" binding:"required"`
	Scene  string `form:"scene" json:"scene" binding:"required"`
	Code   int    `form:"code" json:"code" binding:"required"`
}

//验证码校验
//Auth: Xu
func verifyCode(c *gin.Context) {
	var params verifyRegCodeParams
	err := c.ShouldBindWith(&params, binding.FormPost)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	if errValid := service.ValidateCode(params.Mobile, params.Scene, params.Code); errValid != nil {
		api.SendResponse(c, errValid, nil)
		return
	}
	sign := service.GenValidateCodeSign(params.Mobile, params.Scene)
	data := map[string]string{
		"sign": sign,
	}
	errno.OK.Info = "验证通过"
	api.SendResponse(c, errno.OK, data)
}

type CheckPayPasswordParams struct {
	PayPassword string `form:"password" json:"password"`
	Scene       string `form:"scene" json:"scene"`
}

//校验支付密码
//Auth: Xu
func validatePassword(c *gin.Context) {
	var params CheckPayPasswordParams
	err := c.ShouldBindWith(&params, binding.FormPost)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	uid, _ := service.GetUserIdByRequest(c)
	u, err := service.CheckPayPassword(uid, params.PayPassword)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	if u == "" {
		api.SendResponse(c, errno.SystemErr, nil)
		return
	}
	needCode := service.CheckIfNeedValidateCode(uid, params.Scene)

	data := map[string]interface{}{
		"u":         u,
		"need_code": needCode,
	}

	errno.OK.Info = "OK"
	api.SendResponse(c, errno.OK, data)
	return
}
